package com.example.finaltool.service;

import com.example.finaltool.annotations.Timer;
import com.example.finaltool.consts.Table;
import com.example.finaltool.consts.task.CmmFunctionTask;
import com.example.finaltool.consts.task.Task;
import com.example.finaltool.mapper.CmmFunctionConfigMapper;
import com.example.finaltool.model.CmmFunctionConfigCheck;
import com.example.finaltool.model.DepInfo;
import com.example.finaltool.model.config.Data;
import com.example.finaltool.utils.PrintUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author dengbw
 */
@Service
public class CmmFunctionConfigService {

    CmmFunctionConfigMapper zhenMapper;
    DingCommonService dingCommonService;

    @Autowired
    public CmmFunctionConfigService(CmmFunctionConfigMapper zhenMapper,
                                    DingCommonService dingCommonService) {
        this.zhenMapper = zhenMapper;
        this.dingCommonService = dingCommonService;
    }

    @Timer(Table.CMM_FUNCTION_CONFIG)
    @Transactional(rollbackFor = Exception.class)
    public void save(Data data, Map<String, String> core, DepInfo info) {
        String corpId = data.getCorpId();
        List<Long> existSubIds = getExistSubIds(corpId);
        notExist(findSubInInfo(info, data), existSubIds)
                .forEach(subTenantId -> {
                    List<CmmFunctionConfigCheck> exist = getExistFunction(corpId, subTenantId);
                    Task.zhenConfigTask(corpId, core).stream()
                            .filter(c -> checkPass(core, exist, c))
                            .filter(cmmFunctionTask -> Boolean.TRUE.equals(cmmFunctionTask.getOnlyCun()))
                            .forEach(cmmFunctionTask -> zhenMapper.save(cmmFunctionTask.getUserType(), cmmFunctionTask.getNhType(), cmmFunctionTask.getGbType(),
                                    cmmFunctionTask.getIsCz(), cmmFunctionTask.getSubject(), cmmFunctionTask.getOutUrl(), cmmFunctionTask.getImages(), cmmFunctionTask.getIsMr(), corpId,
                                    cmmFunctionTask.getDefaultImages(), cmmFunctionTask.getSortNo(), cmmFunctionTask.getExtFlag(), subTenantId));

                });
        notExist(info.otherIds(), getExistSubIds(corpId))
                .forEach(subTenantId -> {
                    List<CmmFunctionConfigCheck> exist = getExistFunction(corpId, subTenantId);
                    Task.zhenConfigTask(corpId, core).stream()
                            .filter(c -> checkPass(core, exist, c))
                            .filter(cmmFunctionTask -> Boolean.FALSE.equals(cmmFunctionTask.getOnlyCun()))
                                    .forEach(cmmFunctionTask -> zhenMapper.save(cmmFunctionTask.getUserType(), cmmFunctionTask.getNhType(), cmmFunctionTask.getGbType(),
                                            cmmFunctionTask.getIsCz(), cmmFunctionTask.getSubject(), cmmFunctionTask.getOutUrl(), cmmFunctionTask.getImages(), cmmFunctionTask.getIsMr(), corpId,
                                            cmmFunctionTask.getDefaultImages(), cmmFunctionTask.getSortNo(), cmmFunctionTask.getExtFlag(), subTenantId));
                });
    }

    private boolean checkPass(Map<String, String> core, List<CmmFunctionConfigCheck> exist, CmmFunctionTask c) {
        if (exist.contains(new CmmFunctionConfigCheck(c.getDefaultImages(), c.getUserType(), c.getNhType(), c.getSortNo()))) {
            PrintUtils.showExist(Table.CMM_FUNCTION_CONFIG, c.getSubject());
            return false;
        }
        return !Task.functionNeed.contains(c.getImages()) || !StringUtils.isBlank(core.get(Task.getFunctionLabel(c.getSubject())));
    }

    private List<CmmFunctionConfigCheck> getExistFunction(String corpId, Long subId) {
        return zhenMapper.queryExistFunction(corpId, subId);
    }

    private List<Long> getExistSubIds(String corpId) {
        return zhenMapper.queryExistSubIds(corpId);
    }

    private List<Long> findSubInInfo(DepInfo info, Data data) {
        Map<String, Long> map = new HashMap<>(info.getCunDepInfoList().size());
        info.getCunDepInfoList().forEach(v -> map.put(v.getCunName(), v.getCunDepId()));
        return data.getZhudiwang().stream().map(v -> map.get(v.getCun())).collect(Collectors.toList());
    }

    /**
     * find Long in from that not exist in fromDb
     */
    private List<Long> notExist(List<Long> fromInfo, List<Long> fromDb) {
        List<Long> copy = new ArrayList<>(fromInfo);
        copy.removeAll(fromDb);
        return copy;
    }

    public void updateDefaultImage(String corpId, List<Long> otherIds) {
        otherIds.forEach(subId -> zhenMapper.updateDefaultImage(corpId, subId));
    }
}
